﻿using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;

namespace UDFSocket
{
    public partial class SocketPlus
    {
        ///// <summary>
        ///// 委托声明
        ///// </summary>
        ///// <param name="sender">事件发送者</param>
        ///// <param name="e">事件参数</param>
        //public delegate void ThreadTaskRequest(object sender, EventArgs e);

        ///// <summary>
        ///// 线程任务请求事件
        ///// </summary>
        //public event ThreadTaskRequest OnThreadTaskRequest;


        // 已接受的Socket连接列表
        protected List<Socket> _socketClients;

        /// <summary>
        /// 连接列表操作互斥量
        /// </summary>
        private Mutex _mutexClients;

        /// <summary>
        /// 侦听连接线程
        /// </summary>
        private void ListenThreadAction()
        {

            Listen(1000);
            // 初始化连接列表和互斥量
            _socketClients = new List<Socket>();
            _mutexClients = new Mutex();

            // 接受连接
            while (true)
            {

                //tcpClient = AcceptTcpClient();
                BeginAccept(new AsyncCallback(AcceptCallBack), this);


            }
        }

        /// <summary>
        /// 异步接受连接
        /// </summary>
        /// <param name="ar"></param>
        private void AcceptCallBack(IAsyncResult ar)
        {
            Socket listener = ar.AsyncState as Socket;
            Socket client = null;
            if (listener == null) return;
            try
            {   // 接受挂起的连接请求
                client = listener.EndAccept(ar);
                // 将该连接通信加入线程池队列
                ThreadPool.QueueUserWorkItem(ThreadPoolCallback, client);

                // 连接加入列表
                _mutexClients.WaitOne();
                _socketClients.Add(client);
                _mutexClients.ReleaseMutex();
            }

            

            catch (Exception)
            {   // 加入队列失败
                if (client != null)
                {
                    client.Close();
                }
            }
        }
        /// <summary>
        /// 线程池回调方法
        /// </summary>
        /// <param name="state">回调方法要使用的信息对象</param>
        private void ThreadPoolCallback(Object state)
        {   // 如果无法进行转换，则 as 返回 null 而非引发异常
            Socket client = state as Socket;
            try
            {   // 执行任务
                if (OnThreadTaskRequest != null)
                {
                    OnThreadTaskRequest(client, EventArgs.Empty);
                }
            }

            catch
            {
                // 阻止异常抛出
            }

            finally
            {   // 关闭连接
                client.Close();

                // 从列表中移除连接
                _mutexClients.WaitOne();
                if (_socketClients != null)
                {
                    _socketClients.Remove(client);
                }
                _mutexClients.ReleaseMutex();
            }
        }

    }
}
